﻿/**
 * \file Combat.cs
 * \brief Classe Combat
 * \author ARTUR Vincent
 * \author LAPERDRIX Pierre
 * \version 1.0
 */
namespace Implem
{
    using Interfaces;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Wrapper;
    using Xceed.Wpf.Toolkit;

    /**
     * \class Combat
     * \brief Objet dedie a la gestion des combats entre unites ennemies
     */
    class Combat
    {
        /**
         * \fn unsafe public static void attaque(Position pAttaquant,Position pAttaque)
         * \brief Gestion d'un combat
         * \param pAttaquant la position de l'unite attaquante
         * \param pAttaque la position de l'unite attaquee
         */
        unsafe public static void attaque(Position pAttaquant, Position pAttaque){
            int maxPV = 0;
            List<Unite> l1 = (List<Unite>) Carte.Unites[pAttaquant];
            List<Unite> l2 = (List<Unite>)Carte.Unites[pAttaque];

            bool l1Dir=false, l2Dir=false;

            foreach (Unite u in l1)
            {
                maxPV = Math.Max(maxPV, u.Vie);
                if (u is IDirecteur) l1Dir = true;
            }
            foreach (Unite u in l2)
            {
                maxPV = Math.Max(maxPV, u.Vie);
                if (u is IDirecteur) l2Dir = true;
            }

            Random rand = new Random();
            int nbCoups = rand.Next(3, maxPV + 3);
            bool finCombat = false;
            Unite attaquant;
            Unite defenseur;

             WCombat wc = new WCombat();

            while (nbCoups > 0 && !finCombat)
            {
                //Selection de l'unite dans chaque camp
                attaquant = uniteMeilleureAttaque(pAttaquant);
                defenseur = uniteMeilleureDefense(pAttaque);

                //Deroulement du combat
                int* att = stackalloc int[4];
                att[0] = attaquant.Attaque;
                att[1] = attaquant.Defense;
                att[2] = attaquant.Vie;
                att[3] = attaquant.VieC;
                if (l1Dir && !(attaquant is IDirecteur))
                {
                    att[0] = att[0]*3/2;
                    att[1] = att[1]*3/2;
                }


                int* def = stackalloc int[4];
                def[0] = defenseur.Attaque;
                def[1] = defenseur.Defense;
                def[2] = defenseur.Vie;
                def[3] = defenseur.VieC;

                if (l2Dir && !(defenseur is IDirecteur))
                {
                    def[0] = def[0] * 3 / 2;
                    def[1] = def[1] * 3 / 2;
                }

                int* tmp = wc.attaque(att, def, nbCoups);

                //Traitement post-attaque
                nbCoups = tmp[0];

                //Information au joueur
                string message = "";
                message += "Attaquant : "+attaquant.ToString()+"\n";
                message += "Vie Restante : " + tmp[1] + "\n";
                if (tmp[1] <= 0)
                {
                    message += "L'unité est malheureusement décédée\n\n";
                }
                else
                {
                    message += "\n";
                }
                message += "Défenseur : " + defenseur.ToString() + "\n";
                message += "Vie Restante : " + tmp[2] + "\n";
                if (tmp[2] <= 0)
                {
                    message += "L'unité est malheureusement décédée";
                }


                Xceed.Wpf.Toolkit.MessageBox.Show(message);

                //Diminution des pv des unites combattantes et suppression de ces unites si PV<=0
                attaquant.pertePV(tmp[1]);
                defenseur.pertePV(tmp[2]);

                if (l1.Count == 0) finCombat = true;
                if (l2.Count == 0) finCombat = true;


            }

        }

        /**
         * \fn public static Unite uniteMeilleureDefense(Position p)
         * \brief Retourne l'unite se trouvant a la position p ayant la meilleure defense
         * \param p la position a analyser
         * \return l'unite ayant la meilleure defense
         */
        public static Unite uniteMeilleureDefense(Position p)
        {
            List<Unite>.Enumerator l = ((List<Unite>)Carte.Unites[p]).GetEnumerator();
            l.MoveNext();
            Unite res = (Unite)l.Current;
            Unite u;
            while (l.MoveNext())
            {
                u = (Unite)l.Current;
                if (u.Defense > res.Defense)
                {
                    res = u;
                }
            }
            return res;
        }


        /**
         * \fn public static Unite uniteMeilleureAttaque(Position p)
         * \brief Retourne l'unite se trouvant a la position p ayant la meilleure attaque
         * \param p la position a analyser
         * \return l'unite ayant la meilleure attaque
         */
        public static Unite uniteMeilleureAttaque(Position p)
        {
            List<Unite>.Enumerator l = ((List<Unite>)Carte.Unites[p]).GetEnumerator();
            l.MoveNext();
            Unite res = (Unite)l.Current;
            Unite u;
            while (l.MoveNext())
            {
                u = (Unite)l.Current;
                if (u.Attaque > res.Attaque)
                {
                    res = u;
                }
            }
            return res;
        }
    }
}
